package top.codedance.iotp.slave.service.util;

import com.alibaba.fastjson.JSONObject;
import top.codedance.iotp.common.util.ByteUtils;
import com.intelligt.modbus.jlibmodbus.data.ModbusHoldingRegisters;
import com.intelligt.modbus.jlibmodbus.utils.DataUtils;
import com.serotonin.modbus4j.code.DataType;

import java.math.BigInteger;

public class DataConverter {
    /**
     * 使用Modbus数据类型转换
     * @param holdingRegisters
     * @param datatype
     * @param offset
     * @param jo
     * @throws Exception
     */
    public static void modbusConvert(ModbusHoldingRegisters holdingRegisters, int datatype, int offset, JSONObject jo) throws Exception{
        byte byteV;
        short shortV;
        int intV;
        long longV;
        BigInteger bigIntegerV;
        float floatV;
        double doubleV;
        switch (datatype) {
            case DataType.ONE_BYTE_INT_UNSIGNED_LOWER:
                intV = jo.getInteger("value");
                intV = DataUtils.wordLow(intV);
                holdingRegisters.setInt8At(offset, intV);
                break;
            case DataType.ONE_BYTE_INT_UNSIGNED_UPPER:
                intV = jo.getInteger("value");
                intV = DataUtils.byteHigh(intV);
                holdingRegisters.setInt8At(offset, intV);
                break;
            case DataType.BINARY:
            case DataType.TWO_BYTE_INT_UNSIGNED_SWAPPED:
            case DataType.TWO_BYTE_INT_UNSIGNED:
                intV = jo.getInteger("value");
                holdingRegisters.setInt16At(offset, intV);
                break;
            case DataType.TWO_BYTE_INT_SIGNED_SWAPPED:
            case DataType.TWO_BYTE_INT_SIGNED:
            case DataType.TWO_BYTE_BCD:
                shortV = jo.getShortValue("value");
                holdingRegisters.setSignedInt16At(offset, shortV);
                break;
            case DataType.FOUR_BYTE_INT_UNSIGNED:
                longV = jo.getLong("value");
                longV = ByteUtils.swap(longV);
                intV = ByteUtils.toUnsigned(longV);
                holdingRegisters.setInt32At(offset, intV);
                break;
            case DataType.FOUR_BYTE_INT_SIGNED:
            case DataType.FOUR_BYTE_MOD_10K:
            case DataType.FOUR_BYTE_BCD:
                intV = jo.getInteger("value");
                intV = ByteUtils.swap(intV);
                holdingRegisters.setInt32At(offset, intV);
                break;
            case DataType.FOUR_BYTE_INT_UNSIGNED_SWAPPED:
            case DataType.FOUR_BYTE_INT_UNSIGNED_SWAPPED_SWAPPED:
                longV = jo.getLong("value");
                intV = ByteUtils.toUnsigned(longV);
                holdingRegisters.setInt32At(offset, intV);
                break;
            case DataType.FOUR_BYTE_INT_SIGNED_SWAPPED:
            case DataType.FOUR_BYTE_INT_SIGNED_SWAPPED_SWAPPED:
            case DataType.FOUR_BYTE_MOD_10K_SWAPPED:
            case DataType.FOUR_BYTE_BCD_SWAPPED:
                intV = jo.getInteger("value");
                holdingRegisters.setInt32At(offset, intV);
                break;
            case DataType.EIGHT_BYTE_INT_UNSIGNED: //待查
                bigIntegerV = jo.getBigInteger("value");
                bigIntegerV = ByteUtils.swap(bigIntegerV);
                longV = ByteUtils.toUnsigned(bigIntegerV);
                holdingRegisters.setInt64At(offset, longV);
                break;
            case DataType.EIGHT_BYTE_INT_SIGNED:
            case DataType.EIGHT_BYTE_MOD_10K:
            case DataType.SIX_BYTE_MOD_10K:
                longV = jo.getLong("value");
                longV = ByteUtils.swap(longV);
                holdingRegisters.setInt64At(offset, longV);
                break;
            case DataType.EIGHT_BYTE_INT_UNSIGNED_SWAPPED: //待查
                bigIntegerV = jo.getBigInteger("value");
                longV = ByteUtils.toUnsigned(bigIntegerV);
                holdingRegisters.setInt64At(offset, longV);
                break;
            case DataType.EIGHT_BYTE_INT_SIGNED_SWAPPED:
            case DataType.SIX_BYTE_MOD_10K_SWAPPED :
            case DataType.EIGHT_BYTE_MOD_10K_SWAPPED :
                longV = jo.getLong("value");
                holdingRegisters.setInt64At(offset, longV);
                break;
            case DataType.FOUR_BYTE_FLOAT:
                floatV = jo.getFloat("value");
                floatV = ByteUtils.swap(floatV);
                holdingRegisters.setFloat32At(offset, floatV);
                break;
            case DataType.FOUR_BYTE_FLOAT_SWAPPED:
            case DataType.FOUR_BYTE_FLOAT_SWAPPED_INVERTED:
                floatV = jo.getFloat("value");
                holdingRegisters.setFloat32At(offset, floatV);
                break;
            case DataType.EIGHT_BYTE_FLOAT:
                doubleV = jo.getDouble("value");
                doubleV = ByteUtils.swap(doubleV);
                holdingRegisters.setFloat64At(offset, doubleV);
                break;
            case DataType.EIGHT_BYTE_FLOAT_SWAPPED:
                doubleV = jo.getDouble("value");
                holdingRegisters.setFloat64At(offset, doubleV);
                break;
        }
    }
}
